using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Matrix.Notification.Domain.Notifications;
using Matrix.Notification.Domain.Shared.Notifications;

namespace Matrix.Notification.EntityFrameworkCore.Configurations
{
    /// <summary>
    /// 通知模块实体配置扩展
    /// </summary>
    public static class NotificationModelCreatingExtensions
    {
        /// <summary>
        /// 配置通知模块实体
        /// </summary>
        public static void ConfigureNotification(this ModelBuilder builder)
        {
            builder.Entity<Notification>(b =>
            {
                b.ToTable("AppNotifications");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.Title)
                    .IsRequired()
                    .HasMaxLength(500);

                b.Property(x => x.Content)
                    .IsRequired()
                    .HasMaxLength(4000);

                b.Property(x => x.NotificationCode)
                    .IsRequired()
                    .HasMaxLength(50);

                b.Property(x => x.Type)
                    .HasConversion<int>();

                b.Property(x => x.Priority)
                    .HasConversion<int>();

                b.Property(x => x.Status)
                    .HasConversion<int>();

                b.Property(x => x.Channel)
                    .HasConversion<int>();

                b.Property(x => x.RecipientUserName)
                    .HasMaxLength(256);

                b.Property(x => x.RecipientEmail)
                    .HasMaxLength(256);

                b.Property(x => x.RecipientPhoneNumber)
                    .HasMaxLength(20);

                b.Property(x => x.SenderName)
                    .HasMaxLength(256);

                b.Property(x => x.TemplateName)
                    .HasMaxLength(200);

                b.Property(x => x.Parameters)
                    .HasMaxLength(2000);

                b.Property(x => x.Attachments)
                    .HasMaxLength(2000);

                b.Property(x => x.FailureReason)
                    .HasMaxLength(1000);

                b.Property(x => x.ExternalId)
                    .HasMaxLength(100);

                b.Property(x => x.Category)
                    .HasMaxLength(100);

                b.Property(x => x.BusinessData)
                    .HasMaxLength(2000);

                b.Property(x => x.LocationRestriction)
                    .HasMaxLength(500);

                b.Property(x => x.TimeRestriction)
                    .HasMaxLength(500);

                b.Property(x => x.DeviceRestriction)
                    .HasMaxLength(500);

                b.Property(x => x.RelatedEntityType)
                    .HasMaxLength(100);

                // 配置索引
                b.HasIndex(x => new { x.TenantId, x.RecipientId });
                b.HasIndex(x => new { x.TenantId, x.Status });
                b.HasIndex(x => new { x.TenantId, x.Type });
                b.HasIndex(x => new { x.TenantId, x.Channel });
                b.HasIndex(x => new { x.TenantId, x.Priority });
                b.HasIndex(x => new { x.TenantId, x.ScheduledTime });
                b.HasIndex(x => new { x.TenantId, x.CreatedTime });
                b.HasIndex(x => new { x.TenantId, x.NotificationCode });
                b.HasIndex(x => new { x.TenantId, x.BatchId });
                b.HasIndex(x => new { x.TenantId, x.TemplateId });
                b.HasIndex(x => new { x.TenantId, x.RelatedEntityId, x.RelatedEntityType });
                b.HasIndex(x => new { x.TenantId, x.Category });
            });

            builder.Entity<NotificationTemplate>(b =>
            {
                b.ToTable("AppNotificationTemplates");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.Name)
                    .IsRequired()
                    .HasMaxLength(100);

                b.Property(x => x.DisplayName)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Description)
                    .HasMaxLength(500);

                b.Property(x => x.TemplateCode)
                    .IsRequired()
                    .HasMaxLength(50);

                b.Property(x => x.Type)
                    .HasConversion<int>();

                b.Property(x => x.NotificationType)
                    .HasConversion<int>();

                b.Property(x => x.SupportedChannels)
                    .HasMaxLength(200);

                b.Property(x => x.SubjectTemplate)
                    .HasMaxLength(1000);

                b.Property(x => x.ContentTemplate)
                    .IsRequired()
                    .HasMaxLength(4000);

                b.Property(x => x.HtmlContentTemplate)
                    .HasMaxLength(8000);

                b.Property(x => x.ParameterDefinitions)
                    .HasMaxLength(2000);

                b.Property(x => x.DefaultParameters)
                    .HasMaxLength(2000);

                b.Property(x => x.Tags)
                    .HasMaxLength(500);

                b.Property(x => x.Category)
                    .HasMaxLength(100);

                b.Property(x => x.DefaultLanguage)
                    .IsRequired()
                    .HasMaxLength(10);

                b.Property(x => x.SupportedLanguages)
                    .HasMaxLength(100);

                b.Property(x => x.Version)
                    .IsRequired()
                    .HasMaxLength(20);

                b.Property(x => x.Thumbnail)
                    .HasMaxLength(500);

                b.Property(x => x.PreviewData)
                    .HasMaxLength(2000);

                b.Property(x => x.ApprovalStatus)
                    .HasConversion<int>();

                b.Property(x => x.ApprovalNotes)
                    .HasMaxLength(1000);

                b.Property(x => x.Metadata)
                    .HasMaxLength(2000);

                b.Property(x => x.Settings)
                    .HasMaxLength(2000);

                // 配置索引
                b.HasIndex(x => new { x.TenantId, x.Name }).IsUnique();
                b.HasIndex(x => new { x.TenantId, x.TemplateCode }).IsUnique();
                b.HasIndex(x => new { x.TenantId, x.Type });
                b.HasIndex(x => new { x.TenantId, x.NotificationType });
                b.HasIndex(x => new { x.TenantId, x.Category });
                b.HasIndex(x => new { x.TenantId, x.IsEnabled });
                b.HasIndex(x => new { x.TenantId, x.IsSystem });
                b.HasIndex(x => new { x.TenantId, x.ApprovalStatus });
                b.HasIndex(x => new { x.TenantId, x.Priority });
                b.HasIndex(x => new { x.TenantId, x.ParentTemplateId });
            });

            builder.Entity<NotificationBatch>(b =>
            {
                b.ToTable("AppNotificationBatches");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.Name)
                    .IsRequired()
                    .HasMaxLength(200);

                b.Property(x => x.Description)
                    .HasMaxLength(1000);

                b.Property(x => x.Type)
                    .HasConversion<int>();

                b.Property(x => x.NotificationType)
                    .HasConversion<int>();

                b.Property(x => x.Priority)
                    .HasConversion<int>();

                b.Property(x => x.Channels)
                    .HasMaxLength(200);

                b.Property(x => x.SenderName)
                    .HasMaxLength(256);

                b.Property(x => x.TemplateName)
                    .HasMaxLength(200);

                b.Property(x => x.Status)
                    .HasConversion<int>();

                b.Property(x => x.RecipientList)
                    .IsRequired()
                    .HasMaxLength(4000);

                b.Property(x => x.RecipientFilters)
                    .HasMaxLength(2000);

                b.Property(x => x.Parameters)
                    .HasMaxLength(2000);

                b.Property(x => x.Attachments)
                    .HasMaxLength(2000);

                b.Property(x => x.FailureReason)
                    .HasMaxLength(1000);

                b.Property(x => x.Tags)
                    .HasMaxLength(500);

                b.Property(x => x.BusinessData)
                    .HasMaxLength(2000);

                b.Property(x => x.Settings)
                    .HasMaxLength(2000);

                b.Property(x => x.PauseReason)
                    .HasMaxLength(500);

                b.Property(x => x.BatchCode)
                    .IsRequired()
                    .HasMaxLength(50);

                b.Property(x => x.ExternalBatchId)
                    .HasMaxLength(100);

                b.Property(x => x.RelatedEntityType)
                    .HasMaxLength(100);

                // 配置索引
                b.HasIndex(x => new { x.TenantId, x.BatchCode }).IsUnique();
                b.HasIndex(x => new { x.TenantId, x.Status });
                b.HasIndex(x => new { x.TenantId, x.Type });
                b.HasIndex(x => new { x.TenantId, x.NotificationType });
                b.HasIndex(x => new { x.TenantId, x.Priority });
                b.HasIndex(x => new { x.TenantId, x.ScheduledTime });
                b.HasIndex(x => new { x.TenantId, x.CreatedTime });
                b.HasIndex(x => new { x.TenantId, x.SenderId });
                b.HasIndex(x => new { x.TenantId, x.TemplateId });
                b.HasIndex(x => new { x.TenantId, x.RelatedEntityId, x.RelatedEntityType });
                b.HasIndex(x => new { x.TenantId, x.IsPaused });
            });

            builder.Entity<NotificationSubscription>(b =>
            {
                b.ToTable("AppNotificationSubscriptions");

                b.ConfigureByConvention();

                // 配置属性
                b.Property(x => x.UserName)
                    .IsRequired()
                    .HasMaxLength(100);

                b.Property(x => x.EmailAddress)
                    .HasMaxLength(256);

                b.Property(x => x.PhoneNumber)
                    .HasMaxLength(20);

                b.Property(x => x.SubscribedTypes)
                    .HasMaxLength(500);

                b.Property(x => x.EnabledChannels)
                    .HasMaxLength(200);

                b.Property(x => x.DisabledChannels)
                    .HasMaxLength(200);

                b.Property(x => x.SubscribedCategories)
                    .HasMaxLength(500);

                b.Property(x => x.KeywordFilters)
                    .HasMaxLength(1000);

                b.Property(x => x.TimeRestrictions)
                    .HasMaxLength(1000);

                b.Property(x => x.FrequencyLimits)
                    .HasMaxLength(1000);

                b.Property(x => x.GlobalDisableReason)
                    .HasMaxLength(500);

                b.Property(x => x.DefaultPriority)
                    .HasConversion<int>();

                b.Property(x => x.Settings)
                    .HasMaxLength(2000);

                b.Property(x => x.Personalization)
                    .HasMaxLength(2000);

                b.Property(x => x.DevicePreferences)
                    .HasMaxLength(2000);

                b.Property(x => x.LanguagePreference)
                    .IsRequired()
                    .HasMaxLength(10);

                b.Property(x => x.TimeZonePreference)
                    .IsRequired()
                    .HasMaxLength(50);

                b.Property(x => x.Tags)
                    .HasMaxLength(500);

                b.Property(x => x.Notes)
                    .HasMaxLength(1000);

                // 配置索引
                b.HasIndex(x => new { x.TenantId, x.UserId }).IsUnique();
                b.HasIndex(x => new { x.TenantId, x.UserName });
                b.HasIndex(x => new { x.TenantId, x.EmailAddress });
                b.HasIndex(x => new { x.TenantId, x.PhoneNumber });
                b.HasIndex(x => new { x.TenantId, x.IsEnabled });
                b.HasIndex(x => new { x.TenantId, x.IsGloballyDisabled });
                b.HasIndex(x => new { x.TenantId, x.AllowMarketingNotifications });
                b.HasIndex(x => new { x.TenantId, x.AllowSystemNotifications });
                b.HasIndex(x => new { x.TenantId, x.AllowSecurityNotifications });
                b.HasIndex(x => new { x.TenantId, x.LastActiveTime });
                b.HasIndex(x => new { x.TenantId, x.LastNotificationTime });
            });
        }
    }
}